package com.example.blog.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.blog.config.PublisherAware;
import com.example.blog.domain.*;
import com.example.blog.dto.operationalLogs.OperationLogsDto;
import com.example.blog.event.publisher.LoggingApplicationEvent;
import com.example.blog.event.publisher.UserInformationApplicationEvent;
import com.example.blog.exception.BusinessException;
import com.example.blog.mapper.UserInformationMapper;
import com.example.blog.service.UserInformationService;
import com.example.blog.utils.UploadTheFile;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.*;

@Service
@Transactional
public class UserInformationServiceImpl extends ServiceImpl<UserInformationMapper, UserInformation> implements UserInformationService {
    private final UuIdServiceImpl uuIdService;
    private final UserInformationMapper userInformation;
    private final UserRoleServiceImpl userRoleService;
    private final UserServiceImpl userService;
    private final PublisherAware publisherAware;
    private final WritingsServiceImpl writingsService;

    @Autowired
    public UserInformationServiceImpl(UuIdServiceImpl uuIdService,
                                      UserInformationMapper userInformation,
                                      UserRoleServiceImpl userRoleService,
                                      PublisherAware publisherAware,
                                      WritingsServiceImpl writingsService,
                                      UserServiceImpl userService) {
        this.uuIdService = uuIdService;
        this.userInformation = userInformation;
        this.userRoleService = userRoleService;
        this.userService = userService;
        this.publisherAware = publisherAware;
        this.writingsService = writingsService;
    }

    @Override
    public String uploadUserHeadImg(MultipartFile[] file, String imgPath) {
        //如果文件个数不是一个，并且文件类型不对，返回空
        if (UploadTheFile.fileFormat(file) || file.length != 1) {
            return null;
        }
        UploadTheFile uploadTheFile = new UploadTheFile();
        String[] delImg = new String[]{StringUtils.substringAfterLast(imgPath, "/")};
        Integer length = uploadTheFile.deleteFile(delImg);
        Map<String, String> map = new HashMap<>();
                    LambdaQueryWrapper<UuId> wrapper = new LambdaQueryWrapper<>();
                    StringBuilder stringBuilder = new StringBuilder();
                    String append = String.valueOf(stringBuilder.append("http://www.lyzhnb.top/").append(delImg[0]));
                    uuIdService.remove(wrapper.eq(UuId::getUuidValue, append));
                    List<String> keys = uuIdService.randomUUid(file.length);
                    //上传图片后，返回地址
                    map.put("path", uploadTheFile.uploadFile(file, keys).get(0));
                    System.out.println(map);

                    //插入生成的uuid数据存储
                    List<UuId> uuIds = new ArrayList<>();
                    UuId uuId = new UuId();
                    uuId.setUuidValue(map.get("path"));
                    uuIds.add(uuId);
                    uuIdService.saveBatch(uuIds);
        return map.get("path");
    }


    //新用户信息设置
    @Override
    public Boolean insertUserInfo(Users users) {
        try {
            LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Users::getAccount, users.getUsername());
            Users users_ = new Users();
            users_ = userService.getOne(wrapper);
            UserRole userRole = new UserRole();
            userRole.setUid(users_.getUid());
            userRole.setRid(1);
            userRoleService.save(userRole);
            UserInformation user_info = new UserInformation();
            user_info.setUsername(users.getUsername()); //用户名称
            user_info.setAccount(users.getUsername()); //登录账号
            user_info.setUid(users_.getUid());
            user_info.setEmail(users.getEmail());
            user_info.setMotto("本人很懒什么都没留下");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            user_info.setBorn(sdf.format(new Date()));
            user_info.setAvatar("http://www.lyzhnb.top/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20221010103901.jpg");
            userInformation.insert(user_info);
        } catch (Exception e) {
            return false;
        }
        return true;
    }


    //admin用户信息设置
    @Override
    public String insertAdminInfo(Users users, int rid) {
        LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Users::getAccount, users.getUsername());
        Users users_ = new Users();
        try {
            users_ = userService.getOne(wrapper);
            UserRole userRole = new UserRole();
            userRole.setUid(users_.getUid());
            userRole.setRid(rid);
            userRoleService.save(userRole);
            UserInformation user_info = new UserInformation();
            user_info.setUsername(users.getUsername());
            user_info.setAccount(users.getUsername());
            user_info.setUid(users_.getUid());
            user_info.setEmail(users.getEmail());
            user_info.setMotto("本人很懒什么都没留下");
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            user_info.setBorn(sdf.format(new Date()));
            user_info.setAvatar("http://www.lyzhnb.top/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20221010103901.jpg");
            userInformation.insert(user_info);
        } catch (Exception e) {
            return "";
        }
        return users_.getUsername();
    }

    @Override
    public List<UserInformation> informationCleanup() {
        List<UserInformation> u_info;
        UploadTheFile uploadTheFile = new UploadTheFile();
        try {
            QueryWrapper<UserInformation> ulqw = new QueryWrapper<>();
            LambdaQueryWrapper<Users> wrapper = new LambdaQueryWrapper<>();
            List<String> avatar = new ArrayList<>();
            ulqw.eq("state", -1);
            u_info = userInformation.selectList(ulqw);
            userInformation.delete(new LambdaQueryWrapper<UserInformation>().eq(UserInformation::getState, -1));
            for (UserInformation info : u_info) {
                avatar.add(info.getAvatar());
                wrapper.eq(Users::getUid, info.getUid());
                userService.remove(wrapper);
            }
            String[] fileName = UploadTheFile.intercept(avatar.toArray(new String[avatar.size()]), "/");
            uploadTheFile.deleteFile(fileName);
            LambdaQueryWrapper<UuId> wrapper_ = new LambdaQueryWrapper<>();
            for (String s : avatar) {
                uuIdService.remove(wrapper_.eq(UuId::getUuidValue, s));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return u_info;
    }

    //删除管理员信息
    @Override
    public Integer delAdminUser(Long uid, OperationLogsDto logsDto) {
        Integer remove = 0;
        logsDto.setOutcome(0);
        try {
            UserInformation userInfo = userInformation.selectOne(new LambdaQueryWrapper<UserInformation>().eq(UserInformation::getUid, uid));
            logsDto.setCustomer("用户：".concat("22"));
            LambdaUpdateWrapper<UserInformation> wrapper = new LambdaUpdateWrapper<>();
            remove = userInformation.delete(wrapper.eq(UserInformation::getUid, uid));
            publisherAware.publisher(new UserInformationApplicationEvent(userInfo));
            logsDto.setOutcome(1);
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
        } catch (Exception e) {
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
            throw e;
        }
        return remove;
    }

    //Admin新增管理员
    @Override
    public Integer addAdmin(MultipartFile file,String username, String password,OperationLogsDto logsDto) {
        List<String> list = writingsService.uploadImg(new MultipartFile[]{file});
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        UserInformation userInfo = new UserInformation();
        try{
            userInfo.setAccount(username);
            userInfo.setUsername(username);
            userInfo.setAvatar(list.get(0));
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
            userInfo.setBorn(simpleDateFormat.format(new Date()));
            Users users = new Users(username, username, bCryptPasswordEncoder.encode(password));
            Optional.ofNullable(userService.getOne(new LambdaQueryWrapper<Users>().eq(Users::getAccount,username)))
                 .ifPresent(s->{
                      throw new BusinessException(Response.ERROR_EXISTS,"账户已存在");
                 });
            userService.save(users);
            logsDto.setCustomer(users.getAccount());
            userInfo.setUid(users.getUid());
            userInformation.insert(userInfo);
            userRoleService.save(new UserRole(users.getUid(),2));
            logsDto.setOutcome(1);
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
        }catch (Exception e){
            logsDto.setOutcome(0);
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
            throw e;
        }
        return null;
    }

    //Admin更新用户信息
    @Override
    public Integer updateAdminUserInfo(UserInformation userInfo,OperationLogsDto logsDto) {
        int update = 0;
        try {
            logsDto.setCustomer(userInfo.getUsername());
            UpdateWrapper<UserInformation> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("uid", userInfo.getUid());
            update = userInformation.update(userInfo, updateWrapper);
            logsDto.setOutcome(1);
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
        } catch (Exception e) {
            logsDto.setOutcome(0);
            publisherAware.publisher(new LoggingApplicationEvent(logsDto));
            throw e;
        }
        return update;
    }


}

